﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
//namespace Assets.Script.Event
//{
    public class Event : IEvent
    {
        readonly Dictionary<object, List<Delegate>> EventBuffer = new Dictionary<object, List<Delegate>>();
        public void AddListener(object key, Action handler)
        {
            _IsListenerCanAdd(key, handler);
        }

        public void AddListener<T>(object key, Action<T> handler)
        {
            _IsListenerCanAdd(key, handler);
        }

        public void AddListener<T, U>(object key, Action<T, U> handler)
        {
            _IsListenerCanAdd(key, handler);
        }

        public void AddListener<T, U, V>(object key, Action<T, U, V> handler)
        {
            _IsListenerCanAdd(key, handler);
        }

        public void AddListener<T, U, V, W>(object key, Action<T, U, V, W> handler)
        {
            _IsListenerCanAdd(key, handler);
        }

        public void Dispatch(object key)
        {
            foreach (var dele in _Dispatch(key))
            {
                ((Action)dele)();
            }
        }

        public void Dispatch<T>(object key, T t)
        {
            foreach (var dele in _Dispatch(key))
            {
                ((Action < T > )dele)(t);
            }
        }

        public void Dispatch<T, U>(object key, T t, U u)
        {
            foreach (var dele in _Dispatch(key))
            {
                ((Action<T, U>)dele)(t, u);
            }
        }

        public void Dispatch<T, U, V>(object key, T t, U u, V v)
        {
            foreach (var dele in _Dispatch(key))
            {
                ((Action<T, U, V>)dele)(t,u,v);
            }
        }

        public void Dispatch<T, U, V, W>(object key, T t, U u, V v, W w)
        {
            foreach (var dele in _Dispatch(key))
            {
                ((Action<T, U, V, W>)dele)(t, u, v, w);
            }
        }

        public void RemoveListener(object key, Action handler)
        {
            _IsListenerCanRemove(key, handler);
        }

        public void RemoveListener<T>(object key, Action<T> handler)
        {
            _IsListenerCanRemove(key, handler);
        }

        public void RemoveListener<T, U>(object key, Action<T, U> handler)
        {
            _IsListenerCanRemove(key, handler);
        }

        public void RemoveListener<T, U, V>(object key, Action<T, U, V> handler)
        {
            _IsListenerCanRemove(key, handler);
        }

        public void RemoveListener<T, U, V, W>(object key, Action<T, U, V, W> handler)
        {
            _IsListenerCanRemove(key, handler);
        }

        public void RemoveListener(object key, Delegate handler)
        {
            //Loger.Info("key: " + key);
            _IsListenerCanRemove(key, handler);
        }

        private void _IsListenerCanAdd(object key,Delegate handler)
        {
            if(handler != null)
            {
                if(!EventBuffer.ContainsKey(key))
                {
                    List<Delegate> list = new List<Delegate> { handler };
                    EventBuffer.Add(key, list);
                }
                else
                {
                    EventBuffer[key].Add(handler);
                }
            }
            else
            {
                Debug.LogWarning("AddListener is error....");
            }
        }

        private void _IsListenerCanRemove(object key,Delegate handler)
        {
            if(handler != null)
            {
                if(EventBuffer.ContainsKey(key))
                {
                    if(EventBuffer[key].Count > 0)
                    {
                        EventBuffer[key].Remove(handler);
                    }
                    else
                    {
                        EventBuffer.Remove(key);
                    }
                }
                else
                {
                    Debug.LogWarning(key.ToString() + "is not exit...");
                }
            }
            else
            {
                Debug.LogWarning("handler is null ... ");
            }
        }

        private IEnumerable<Delegate> _Dispatch(object key)
        {
            List<Delegate> list = new List<Delegate>();
            if(EventBuffer.ContainsKey(key))
            {
                list = EventBuffer[key];
            }
            else
            {
                Debug.LogWarning(key.ToString() + "is not exit...");
            }
            return list;
        }
    }
//}
